<?php


namespace app\api\service;

use app\api\model\Order as OrderModel;
use app\api\model\OrderProduct as OrderProductModel;
use app\api\model\Product as ProductModel;
use app\api\model\UserAddress as UserAddressModel;

class Order
{
    const UNPAID = 1;   // 未支付
    const ISPAID = 2;   // 已支付
    const ISDELIVER = 3;    // 已发货
    const PAY_BUT_OUT_OF = 4; // 已支付但库存不足


    protected static  $products;
    protected static  $user_id;
    protected static  $orderProducts;

    /**
     * 下单相关逻辑处理
     * @param $uid
     * @param $orderProducts
     * @return array
     * @throws \app\lib\exception\ThrowError
     */
    public static function place($uid, $orderProducts)
    {
        self::$user_id = $uid;
        self::$orderProducts = $orderProducts;
        $productIds = array_column(self::$orderProducts, 'product_id');
        self::$products = ProductModel::getProductsByOrderProducts($productIds);

        // 获取商品状态
        $status = self::getOrderStatus();

        // 下单商品信息校验不通过
        if (!$status['pass'])
        {
            $status['order_id'] = -1;
            $status['order_no'] = -1;
            $status['create_time'] = 0;
            return $status;
        }

        // 开始创建订单，组装数据
        $snapOrder = self::generateSnapOrder($status);

        // 创建订单
        $orderInfo = OrderModel::createSnapOrder($uid, $snapOrder, self::$orderProducts);

        $orderInfo['pass'] = true;
        return $orderInfo;
    }

    /**
     * 组装订单信息
     * @param $status
     * @return array
     */
    private static function generateSnapOrder($status)
    {
        $result = [
            'totalPrice' => $status['orderPrice'],
            'totalCount' => $status['totalCount'],
            'snapImg' => self::$products[0]['main_img_url'],
            'snapName' => self::$products[0]['name'],
            'snapItems' => $status['pStatusArray'],
            'snapAddress' => UserAddressModel::getUserAddress(self::$user_id)
        ];
        $result['snapName'] .= $result['totalCount'] > 1 ? '等' : '';
        $result['order_no'] = self::makeOrderNo();

        return $result;
    }

    /**
     * 创建订单号
     * @return string
     */
    public static function makeOrderNo()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K');
        $orderSn =
            $yCode[intval(date('Y')) - 2018] . strtoupper(dechex(date('m'))) . date(
                'd') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf(
                '%02d', rand(0, 99));
        return $orderSn;
    }

    /**
     * 判断订单状态是否正常
     * @return array
     * @throws \app\lib\exception\ThrowError
     */
    private static function getOrderStatus()
    {
        $status = [
            'pass' => true, //商品库存是否为空,
            'orderPrice' => 0, // 订单总价格,
            'totalCount' => 0,
            'pStatusArray' => [] // 订单的商品详情数据
        ];

        $products = array_column(self::$products ,null, 'id');
        foreach (self::$orderProducts as $oProduct)
        {
            $pStatus = self::getProductStatus($oProduct['product_id'], $oProduct['count'], $products);

            if (!$pStatus['haveStock'])
            {
                $status['pass'] = false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            $status['totalCount'] += $pStatus['counts'];
            array_push($status['pStatusArray'], $pStatus);
        }
        return $status;
    }


    /**
     * 判断商品是否存在、库存是否充足
     * @param $oPid
     * @param $oCount
     * @return array
     * @throws \app\lib\exception\ThrowError
     */
    private static function getProductStatus($oPid, $oCount, $products)
    {
        if (!isset($products[$oPid]))
        {
            T(601001, ['id' => $oPid]);
        }

        $product = $products[$oPid];
        $pStatus = [
            'id' => $oPid,
            'haveStock' => false,
            'counts' => $oCount,
            'price' => $product['price'],
            'main_img_url' => $product['main_img_url'],
            'name' => $product['name'],     // 商品名称
            'totalPrice' => $oCount *  $product['price']// 这个商品的总价格
        ];

        // 检测库存是否充足
        if (($product['stock'] - $oCount) >= 0)
        {
            $pStatus['haveStock'] = true;
        }
        return $pStatus;
    }

    /**
     * 根据订单号检查库存量是否充足
     * @param $orderId
     */
    public static function getOrderStatusByOrderId($orderId)
    {
        self::$orderProducts = OrderProductModel::getOrderProductByOrderId($orderId);
        $productIds = array_column(self::$orderProducts, 'product_id');
        self::$products = ProductModel::getProductsByOrderProducts($productIds);
        $status = self::getOrderStatus();
        return $status;
    }

    /**
     * 检查订单是否有效
     * @param $orderId
     * @return \think\db\Query
     * @throws \app\lib\exception\ThrowError
     * @throws \think\Exception
     */
    public static function orderIsValid($orderId)
    {
        $orderInfo = OrderModel::where('id', '=', $orderId)->find();

        // 检查订单是否存在
        if (empty($orderInfo))
        {
            T(601002);
        }

        // 检查订单状态是否是待支付
        if ($orderInfo->status != self::UNPAID)
        {
            T(601003);
        }

        // 检查订单是否是当前用户的
        if (!UserToken::checkCurrentUserId($orderInfo->user_id))
        {
            T(601004);
        }

        return $orderInfo;
    }

    /**
     * 更新预支付ID
     * @param $orderId
     * @param $prePayId
     * @return OrderModel
     */
    public static function savePrepayId($orderId, $prePayId)
    {
        return OrderModel::update(['prepay_id' => $prePayId], ['id' => $orderId]);
    }

}